package com.qezhhnjy.demo.hadoop.config;

import com.qezhhnjy.demo.hadoop.pool.HadoopFactory;
import lombok.Data;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.hadoop.fs.FileSystem;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("hadoop-pool")
@Data
public class HadoopConfig {

    private String ip;
    private int    port;

    private int     maxIdle;
    private int     minIdle;
    private int     maxTotal;
    private int     minEvictableIdleTimeMillis;
    private int     timeBetweenEvictionRunsMillis;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean testWhileIdle;
    private int     maxWaitMillis;
    private boolean lifo;
    private boolean blockWhenExhausted;
    private int     numTestPerEvictionRun;

    public String uri() {
        return String.format("hdfs://%s:%d/", ip, port);
    }

    @Bean
    public GenericObjectPoolConfig<FileSystem> poolConfig() {
        GenericObjectPoolConfig<FileSystem> config = new GenericObjectPoolConfig<>();
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);
        config.setMaxTotal(maxTotal);

        // 逐出连接的最小空闲时间
        config.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        // 逐出扫描的时间间隔,如果为负数,则不运行逐出线程,默认-1
        config.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        // 在获取对象的时间检查有效性,默认false
        config.setTestOnBorrow(testOnBorrow);
        // 在归还对象的时候检查有效性
        config.setTestOnReturn(testOnReturn);
        // 在空闲时检查有效性,默认false
        config.setTestWhileIdle(testWhileIdle);
        // 最大等待时间,默认的值为-1,表示无限等待
        config.setMaxWaitMillis(maxWaitMillis);
        // 是否启用后进先出,默认true
        config.setLifo(lifo);
        // 连接耗尽时是否阻塞,false报异常,true阻塞直到超时,默认true
        config.setBlockWhenExhausted(blockWhenExhausted);
        // 每次逐出检查时,逐出的最大数目, 默认为3
        config.setNumTestsPerEvictionRun(numTestPerEvictionRun);
        return config;
    }

    @Bean
    public HadoopFactory factory() {
        org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
        conf.set("fs.defaultFS", uri());
        HadoopFactory factory = new HadoopFactory();
        factory.setConfiguration(conf);
        return factory;
    }

    @Bean
    public GenericObjectPool<FileSystem> pool(HadoopFactory factory, GenericObjectPoolConfig<FileSystem> poolConfig) {
        return new GenericObjectPool<>(factory, poolConfig);
    }
}
